/*
 * Copyright 1999-2017 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package studio.raptor.sqlparser.parser;

import static studio.raptor.sqlparser.parser.LayoutCharacters.EOI;

public class CharTypes {

  private final static boolean[] hexFlags = new boolean[256];
  private final static boolean[] firstIdentifierFlags = new boolean[256];
  private final static boolean[] identifierFlags = new boolean[256];
  private final static boolean[] whitespaceFlags = new boolean[256];

  static {
    for (char c = 0; c < hexFlags.length; ++c) {
      if (c >= 'A' && c <= 'F') {
        hexFlags[c] = true;
      } else if (c >= 'a' && c <= 'f') {
        hexFlags[c] = true;
      } else if (c >= '0' && c <= '9') {
        hexFlags[c] = true;
      }
    }
  }

  static {
    for (char c = 0; c < firstIdentifierFlags.length; ++c) {
      if (c >= 'A' && c <= 'Z') {
        firstIdentifierFlags[c] = true;
      } else if (c >= 'a' && c <= 'z') {
        firstIdentifierFlags[c] = true;
      }
    }
    firstIdentifierFlags['`'] = true;
    firstIdentifierFlags['_'] = true;
    firstIdentifierFlags['$'] = true;
  }

  static {
    for (char c = 0; c < identifierFlags.length; ++c) {
      if (c >= 'A' && c <= 'Z') {
        identifierFlags[c] = true;
      } else if (c >= 'a' && c <= 'z') {
        identifierFlags[c] = true;
      } else if (c >= '0' && c <= '9') {
        identifierFlags[c] = true;
      }
    }
    // identifierFlags['`'] = true;
    identifierFlags['_'] = true;
    identifierFlags['$'] = true;
    identifierFlags['#'] = true;
  }

  static {
    for (int i = 0; i <= 32; ++i) {
      whitespaceFlags[i] = true;
    }

    whitespaceFlags[EOI] = false;
    for (int i = 0x7F; i <= 0xA0; ++i) {
      whitespaceFlags[i] = true;
    }

    whitespaceFlags[160] = true; // 特别处理
  }

  public static boolean isHex(char c) {
    return c < 256 && hexFlags[c];
  }

  public static boolean isDigit(char c) {
    return c >= '0' && c <= '9';
  }

  public static boolean isFirstIdentifierChar(char c) {
    if (c <= firstIdentifierFlags.length) {
      return firstIdentifierFlags[c];
    }
    return c != '　' && c != '，';
  }

  public static boolean isIdentifierChar(char c) {
    if (c <= identifierFlags.length) {
      return identifierFlags[c];
    }
    return c != '　' && c != '，';
  }

  /**
   * @return false if {@link LayoutCharacters#EOI}
   */
  public static boolean isWhitespace(char c) {
    return (c <= whitespaceFlags.length && whitespaceFlags[c]) //
        || c == '　'; // Chinese space
  }

}
